package com.soft.baseexercise.exercise;

import java.util.Scanner;

/**
 * @author yzh
 * @desc TODO
 * @date 2025/4/18
 */
public class GoBang {
    private static final char EMPTY = '*';
    private static final char BLACK = '@';
    private static final char WHITE = 'O';

    private char[][] board;
    private int size;
    private boolean isBlackTurn;

    public GoBang(int size) {
        this.size = size;
        this.board = new char[size][size];
        this.isBlackTurn = true;
        initializeBoard();
    }

    // 初始化棋盘
    private void initializeBoard() {
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                board[i][j] = EMPTY;
            }
        }
    }

    public void startGame() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("即将开局");
        printBoard();

        while (true) {
            String currentPlayer = isBlackTurn ? "黑方" : "白方";
            System.out.print("请" + currentPlayer + "下子：");
            String input = scanner.nextLine().trim().toLowerCase();

            if (!isValidInput(input)) {
                System.out.println("输入无效，请重新输入（格式如：ac）");
                continue;
            }

            // 获取行列值
            int row = input.charAt(0) - 'a';
            int col = input.charAt(1) - 'a';

            if (row < 0 || row >= size || col < 0 || col >= size) {
                System.out.println("坐标超出范围，请重新输入");
                continue;
            }

            if (board[row][col] != EMPTY) {
                System.out.println("该位置已有棋子，请重新选择");
                continue;
            }

            board[row][col] = isBlackTurn ? BLACK : WHITE;
            printBoard();

            if (checkWin(row, col)) {
                System.out.println(currentPlayer + "获胜！游戏结束");
                break;
            }

            isBlackTurn = !isBlackTurn;
        }
    }

    private boolean isValidInput(String input) {
        return input.length() == 2
                && Character.isLetter(input.charAt(0))
                && Character.isLetter(input.charAt(1));
    }

    private boolean checkWin(int row, int col) {
        // 检查水平方向：向左数 + 向右数 - 1（因为当前点被数了两次）
        if (countConsecutive(row, col, 0, 1) + countConsecutive(row, col, 0, -1) - 1 >= 5) {
            return true;
        }

        // 检查垂直方向：向上数 + 向下数 - 1
        if (countConsecutive(row, col, 1, 0) + countConsecutive(row, col, -1, 0) - 1 >= 5) {
            return true;
        }

        // 检查对角线（左上到右下）：右下数 + 左上数 - 1
        if (countConsecutive(row, col, 1, 1) + countConsecutive(row, col, -1, -1) - 1 >= 5) {
            return true;
        }

        // 检查对角线（右上到左下）：左下数 + 右上数 - 1
        if (countConsecutive(row, col, 1, -1) + countConsecutive(row, col, -1, 1) - 1 >= 5) {
            return true;
        }

        return false;
    }

    private int countConsecutive(int row, int col, int rowStep, int colStep) {
        char currentStone = board[row][col]; // 当前棋子颜色
        int count = 0;

        int r = row;
        int c = col;

        // 沿着指定方向一步步走，直到棋盘边界或遇到不同颜色的棋子
        while (r >= 0 && r < size && c >= 0 && c < size && board[r][c] == currentStone) {
            count++;
            r += rowStep; // 行方向步进
            c += colStep; // 列方向步进
        }

        return count;
    }

    private void printBoard() {
        // 打印行标签和棋盘
        for (int i = 0; i < size; i++) {
            System.out.print((char)('a' + i) + " ");
            for (int j = 0; j < size; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }

        // 打印列标签
        System.out.print("  ");
        for (int j = 0; j < size; j++) {
            System.out.print((char)('a' + j) + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入棋盘的大小，至少为5：");
        int size = sc.nextInt();

        if (size < 5) {
            System.out.println("棋盘大小不能小于5！");
            return;
        }

        GoBang game = new GoBang(size);
        game.startGame();
    }
}
